﻿using AiQiuQuan.Sport.Model.Enums;
using AiQiuQuan.Sport.Model.Models;
using AiQiuQuan.Sport.WebApi.Repositories;
using Microsoft.EntityFrameworkCore;

namespace AiQiuQuan.Sport.WebApi.Services.Impl
{
    /// <summary>
    /// 场馆订单数据管理
    /// </summary>
    public class VenueOrderService : IVenueOrderService
    {
        private readonly ISiteOrderRepository _siteOrderRepository;
        private readonly ISiteOrderDetailRepository _orderDetailRepository;
        private readonly IBaseUserRepository _baseUserRepository;
        private readonly IPayOrderRepository _payOrderRepository;
        private readonly IVenueInfoRepository _venueInfoRepository;

        /// <summary>
        /// ctor
        /// </summary>
        public VenueOrderService(
            ISiteOrderRepository siteOrderRepository,
            ISiteOrderDetailRepository orderDetailRepository,
            IBaseUserRepository baseUserRepository,
            IPayOrderRepository payOrderRepository,
            IVenueInfoRepository venueInfoRepository)
        {
            _siteOrderRepository = siteOrderRepository;
            _orderDetailRepository = orderDetailRepository;
            _baseUserRepository = baseUserRepository;
            _payOrderRepository = payOrderRepository;
            _venueInfoRepository = venueInfoRepository;
        }

        /// <summary>
        /// 通过场馆开始日期查询订单列表
        /// </summary>
        public async Task<PageResult<VenueOrderRefundManageDto>> GetOrderListByDateAsync(VenueOrderDateRequestDto request)
        {
            var dd = request.QueryDate.Date;
            var stateList = new List<VenueOrderStateEnum> { VenueOrderStateEnum.NoUse, VenueOrderStateEnum.NoEvaluate, VenueOrderStateEnum.Refund, VenueOrderStateEnum.Completed };
            var queryable = _siteOrderRepository.AsNoTracking()
                .Where(m => m.VenueInfoID == request.VenueId && stateList.Contains(m.SO_State) && _orderDetailRepository.Any(s =>
                    s.SiteOrderID == m.ID && s.SiteDate == dd));

            var queryable1 = from q in queryable
                             join user in _baseUserRepository.AsNoTracking()
                             on q.BaseUserID equals user.ID into userd
                             from user in userd.DefaultIfEmpty()
                             join payorder in _payOrderRepository.AsNoTracking()
                             on q.ID equals payorder.BusinessId into paorderd
                             from payorder in paorderd.DefaultIfEmpty()
                             select new VenueOrderRefundManageDto
                             {
                                 OrderId = q.ID,
                                 OrderNo = q.SO_OrderNo,
                                 State = q.SO_State,
                                 RefundAmount = _payOrderRepository.Where(m => m.BusinessId == q.ID).Sum(m => m.RefundAmount),
                                 PayAmount = q.SO_ActualPrice,
                                 CardAmount = q.CardAmount,
                                 PayType = q.PayType,
                                 MemberCardType = q.MemberCardType,
                                 StartDate = dd,
                                 StartTime = "",
                                 EndTime = "",
                                 UserName = user.U_NickName,
                                 PhoneNo = user.U_PhoneNum,
                                 CreateTime = q.CreateTime,
                                 PayState = payorder.PayState
                             };
            var result = await queryable1.OrderByDescending(m => m.CreateTime).PageListAsync(request);
            foreach (var item in result.Result)
            {
                var list = await _orderDetailRepository.AsNoTracking().Where(m => m.SiteOrderID == item.OrderId).ToListAsync();
                if (list.Any())
                {
                    list = list.OrderBy(m => m.SiteStartTime).ToList();
                    item.StartTime = list[0].SiteStartTime;
                    item.EndTime = list[list.Count - 1].SiteEndTime;
                    item.SiteName = list[0].SiteName;
                }
            }

            return result;
        }

        /// <summary>
        /// 查询订单
        /// </summary>
        /// <param name="id">订单ID</param>
        public async Task<SiteOrderDto> GetAsync(Guid id)
        {
            var queryable = from order in _siteOrderRepository.AsNoTracking()
                            join venue in _venueInfoRepository.AsNoTracking()
                            on order.VenueInfoID equals venue.ID
                            join user in _baseUserRepository.AsNoTracking()
                            on order.BaseUserID equals user.ID
                            join payorder in _payOrderRepository.AsNoTracking()
                            on order.ID equals payorder.BusinessId into payorderd
                            from payorder in payorderd.DefaultIfEmpty()
                            where order.ID == id
                            select new SiteOrderDto
                            {
                                ID = order.ID,
                                SO_OrderNo = order.SO_OrderNo,
                                SO_WeChatOrderNo = order.SO_WeChatOrderNo,
                                SO_OrderRemark = order.SO_OrderRemark,
                                BaseUserID = order.BaseUserID,
                                VenueInfoID = order.VenueInfoID,
                                SO_TotalPrice = order.SO_TotalPrice,
                                SO_DiscountPrice = order.SO_DiscountPrice,
                                SO_ActualPrice = order.SO_ActualPrice,
                                SO_State = order.SO_State,
                                PayType = order.PayType,
                                MemberCardType = order.MemberCardType,
                                CardAmount = order.CardAmount,
                                UserVenueCardId = order.UserVenueCardId,
                                CardDiscount = order.CardDiscount,
                                SO_Explain = order.SO_Explain,
                                SO_CancelRemark = order.SO_CancelRemark,
                                SO_CancelReason = order.SO_CancelReason,
                                SO_CancelRole = order.SO_CancelRole,
                                SO_CancelTime = order.SO_CancelTime,
                                SO_UseIntegral = order.SO_UseIntegral,
                                CreateTime = order.CreateTime,
                                VenueName = venue.VI_Name,
                                NickName = user.U_NickName,
                                PhoneNo = user.U_PhoneNum,
                                PayState = payorder.PayState,
                                RefundAmount = payorder.RefundAmount
                            };
            var result = await queryable.FirstOrDefaultAsync();
            if (result != null)
            {
                await SetOrderDetailInfoAsync(result);
            }

            return result;
        }

        /// <summary>
        /// 分页请求
        /// </summary>
        public async Task<PageResult<SiteOrderDto>> PageListAsync(VenueOrderPageRequestDto request)
        {
            var queryable = GeneratePageListQueryable(request);
            var pageList = await queryable.OrderByDescending(m => m.CreateTime).PageListAsync(request);
            foreach (var item in pageList.Result)
            {
                await SetOrderDetailInfoAsync(item);
            }

            return pageList;

        }

        #region private methods
        private IQueryable<SiteOrderDto> GeneratePageListQueryable(VenueOrderPageRequestDto request)
        {
            var queryable = from order in _siteOrderRepository.AsNoTracking()
                            join venue in _venueInfoRepository.AsNoTracking()
                            on order.VenueInfoID equals venue.ID
                            join user in _baseUserRepository.AsNoTracking()
                            on order.BaseUserID equals user.ID
                            join payorder in _payOrderRepository.AsNoTracking()
                            on order.ID equals payorder.BusinessId into payorderd
                            from payorder in payorderd.DefaultIfEmpty()
                            select new SiteOrderDto
                            {
                                ID = order.ID,
                                SO_OrderNo = order.SO_OrderNo,
                                SO_WeChatOrderNo = order.SO_WeChatOrderNo,
                                SO_OrderRemark = order.SO_OrderRemark,
                                BaseUserID = order.BaseUserID,
                                VenueInfoID = order.VenueInfoID,
                                SO_TotalPrice = order.SO_TotalPrice,
                                SO_DiscountPrice = order.SO_DiscountPrice,
                                SO_ActualPrice = order.SO_ActualPrice,
                                SO_State = order.SO_State,
                                PayType = order.PayType,
                                MemberCardType = order.MemberCardType,
                                CardAmount = order.CardAmount,
                                UserVenueCardId = order.UserVenueCardId,
                                CardDiscount = order.CardDiscount,
                                SO_Explain = order.SO_Explain,
                                SO_CancelRemark = order.SO_CancelRemark,
                                SO_CancelReason = order.SO_CancelReason,
                                SO_CancelRole = order.SO_CancelRole,
                                SO_CancelTime = order.SO_CancelTime,
                                SO_UseIntegral = order.SO_UseIntegral,
                                CreateTime = order.CreateTime,
                                VenueName = venue.VI_Name,
                                NickName = user.U_NickName,
                                PhoneNo = user.U_PhoneNum,
                                PayState = payorder.PayState,
                                RefundAmount = payorder.RefundAmount
                            };
            if (!string.IsNullOrWhiteSpace(request.OrderNo))
            {
                queryable = queryable.Where(m => m.SO_OrderNo.Contains(request.OrderNo));
            }

            if (!string.IsNullOrWhiteSpace(request.VenueName))
            {
                queryable = queryable.Where(m => m.VenueName.Contains(request.VenueName));
            }

            if (!string.IsNullOrWhiteSpace(request.PhoneNo))
            {
                queryable = queryable.Where(m => m.PhoneNo.Contains(request.PhoneNo));
            }

            if (!string.IsNullOrWhiteSpace(request.NickName))
            {
                queryable = queryable.Where(m => m.NickName.Contains(request.NickName));
            }

            if (request.SiteDate.HasValue)
            {
                queryable = queryable.Where(m => _orderDetailRepository.Any(j => j.SiteOrderID == m.ID && j.SiteDate == request.SiteDate.Value.Date));
            }

            return queryable;
        }

        /// <summary>
        /// 设置订单明细相关信息
        /// </summary>
        private async Task SetOrderDetailInfoAsync(SiteOrderDto item)
        {
            var detailList = await _orderDetailRepository.AsNoTracking().Where(m => m.SiteOrderID == item.ID).ToListAsync();
            if (detailList.Any())
            {
                detailList = detailList.OrderBy(m => m.SiteStartTime).ToList();
                item.SiteDate = detailList[0].SiteDate;
                item.StieStartTime = detailList[0].SiteStartTime;
                item.SiteEndTime = detailList[detailList.Count - 1].SiteEndTime;
            }
        }
        #endregion
    }
}